package com.qby.framework.filter.login;

import com.qby.common.utils.SecurityUtils;
import com.qby.framework.constant.RedisConstant;
import com.qby.framework.redis.RedisCache;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @description: 登录过滤器
 * @author: qiu bo yang
 * @create: 2020-03-25 18:55
 */
@Slf4j
public class LoginFilter implements Filter {
    @Autowired
    private NoAuthConfig noAuthConfig;

    private String[] noAuthUrls;

    @Autowired
    private RedisCache redisCache;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //初始化，无需鉴权链接
        initNoAuthUrl(noAuthConfig.getNotAuthUrls());
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        boolean check = false;
        try {
            //获取请求链接
            String requestUri = request.getRequestURI();
            boolean ignore = matching(requestUri, noAuthUrls);
            if (ignore) {
                //拿到token
                String token = request.getHeader(noAuthConfig.getTokenHeader());
                if (StringUtils.isNotBlank(token)) {
                    Integer userId = redisCache.getCacheObject(RedisConstant.USER_TOKEN + token);
                    // token验证成功得到用户信息
                    if (userId != null) {
                        SecurityUtils.setUserId(userId);
                        check = true;
                    }
                }
            } else {
                check = true;
            }
            //通过
            if (check) {
                filterChain.doFilter(servletRequest, servletResponse);
                response.setStatus(HttpStatus.OK.value());
            } else {
                //鉴权失败返回401
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info(e.getMessage());
            //鉴权失败返回401
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
        }
    }

    @Override
    public void destroy() {

    }

    /**
     * 初始化，无需鉴权链接
     *
     * @param params
     */
    private void initNoAuthUrl(String... params) {
        noAuthUrls = params;
    }

    /**
     * 验证访问的路径是否需要验证,true需要验证，false不需要验证
     *
     * @param requestUri 请求链接
     * @param noAuthUrls 无需鉴权链接
     * @return
     */
    private boolean matching(String requestUri, String[] noAuthUrls) {
        boolean result = true;
        if (noAuthUrls != null) {
            for (String notAuthUrl : noAuthUrls) {
                if (notAuthUrl.indexOf("/**") == -1) {
                    if (requestUri.equals(notAuthUrl)) {
                        result = false;
                    }
                } else {
                    String notAuthUrlTemp = notAuthUrl.replace("/**", "");
                    if (requestUri.startsWith(notAuthUrlTemp)) {
                        result = false;
                    }
                }
            }
        }
        return result;
    }
}
